package org.sixtynine.stock.controller.front;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.sixtynine.stock.Constants;
import org.sixtynine.stock.Constants.CommonData;
import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.model.ColData;
import org.sixtynine.stock.model.ColModel;
import org.sixtynine.stock.model.GridData;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.result.DividendResult;
import org.sixtynine.stock.result.Sortable;
import org.sixtynine.stock.service.StockManagerService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.util.StockComparator;
import org.sixtynine.stock.util.StockComparator.ShareResultComparator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilanka
 * 
 */
@Controller
public class DividendHistoryController extends AbstractGridController {

	@Autowired
	private StockManagerService service;

	@Autowired
	DataManagerService dataManagerService;

	@RequestMapping(value = "/dividendhistory/main")
	public ModelAndView showResults() {
		ModelAndView modelAndView = new ModelAndView("/dividendhistory/main");

		showBannar(modelAndView);
		List<BaseEntity> companies = dataManagerService
				.getData(CommonData.COMPANY.toString());
		modelAndView.addObject("companyMap", companies);
		modelAndView.addObject("criteria", new LoadingSearchCriteria());

		return modelAndView;
	}

	@RequestMapping(value = "/dividendhistory/list", method = RequestMethod.POST)
	@ResponseBody
	public GridData getData(
			@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
			@RequestParam(value = "rows", required = false) Integer rows,
			@RequestParam(value = "sidx", required = false) String sidx,
			@RequestParam(value = "sord", required = false) String sord,
			@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {

		return getGridDividendData(criteria.getCompanyId(),
				criteria.getFromDate(), criteria.getToDate(), page, rows, sidx,
				sord, request);

	}

	@RequestMapping(value = "/dividendhistory/colData", method = RequestMethod.GET)
	@ResponseBody
	public ColData getColumnData() {
		return getColData();
	}

	@Override
	public ColData getColData() {
		ColData colData = new ColData();

		List<ColModel> colModels = new ArrayList<ColModel>();

		colModels.add(new ColModel("ticker"));
		colModels.add(new ColModel("companyName"));
		colModels.add(new ColModel("date"));
		colModels.add(new ColModel("dividendPerShare", "number", "right"));
		colModels.add(new ColModel("adjDividendPerShare", "number", "right"));
		colModels.add(new ColModel("rightIssue"));
		colModels.add(new ColModel("stockSplits"));
		colModels.add(new ColModel("bonusIssue"));

		colData.setColModel(colModels);

		List<String> colNames = new ArrayList<String>();

		colNames.add("Ticker");
		colNames.add("Company Name");
		colNames.add("Date");
		colNames.add("Dividend per share");
		colNames.add("Adjusted dividend per share");
		colNames.add("Right Issue");
		colNames.add("Stock Splits");
		colNames.add("Bonus Issue");
		colData.setColNames(colNames);
		return colData;
	}

	/**
	 * @param companyId
	 * @param fromDate
	 * @param toDate
	 * @param page
	 * @param rows
	 * @param session
	 * @return
	 */
	public ReturnData<List<DividendResult>> getGridDividendData(int companyId,
			Date fromDate, Date toDate, int page, Integer rows, String sidx,
			String sord, HttpSession session) {

		ReturnData<List<DividendResult>> output = new ReturnData<List<DividendResult>>();

		List<DividendResult> results = null;
		if (rows != null && page > 1) {
			results = (List<DividendResult>) session
					.getAttribute(Constants.SESSION_RESULTS);
		}

		if (results == null) {
			ReturnData<List<DividendResult>> returnData = service
					.searchDividends(companyId, fromDate, toDate);

			if (returnData._isSuccess()) {
				results = returnData.getData();
				session.setAttribute(Constants.SESSION_RESULTS, results);
			}
		}

		if (!StringUtils.isEmpty(sidx) && !StringUtils.isEmpty(sord)) {
			Sortable sortable = new Sortable(sidx, sord);
			ShareResultComparator<DividendResult> comparator = (ShareResultComparator<DividendResult>) StockComparator
					.getInstance(StockComparator.DIVIDEND_RESULT_COMPARATOR,
							sortable);
			comparator.setSortable(sortable);

			Collections.sort(results, comparator);
		}

		int startIndex = (page - 1) * rows;
		int endIndex = startIndex + rows;
		endIndex = endIndex > results.size() ? results.size() : endIndex;
		output.setData(results.subList(startIndex, endIndex));
		output.setNo(results.size());

		return output;
	}

	/**
	 * @param companyId
	 * @param fromDate
	 * @param toDate
	 * @param page
	 * @param rows
	 * @param request
	 * @return
	 */
	public GridData<DividendResult> getGridDividendData(int companyId,
			Date fromDate, Date toDate, int page, Integer rows, String sidx,
			String sord, HttpServletRequest request) {
		GridData<DividendResult> gridData = new GridData<DividendResult>();

		HttpSession session = request.getSession();
		ReturnData<List<DividendResult>> data = getGridDividendData(companyId,
				fromDate, toDate, page, rows, sidx, sord, session);

		gridData.setData(data.getData());
		gridData.setPage(page);

		gridData.setTotal((data.getNo() / pageSize) + 1);
		gridData.setRecords(data.getNo());

		return gridData;
	}

}
